package com.luo.sc.oidc.authserver.handler.login;

import com.luo.sc.oidc.authserver.enums.AuthenticaionResultCodeEnum;
import com.luo.sc.oidc.authserver.utils.HttpContextUtils;
import com.luo.sc.oidc.authserver.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Optional;

/**
 * 通用登录 - 成功处理器 - 返回成功响应结果（支持Ajax）
 *
 * @author Luohq
 * @date 2022-03-11
 * @see org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler
 */
@Slf4j
public class UniLoginRespJsonAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private final RequestCache requestCache;

    public UniLoginRespJsonAuthenticationSuccessHandler(RequestCache requestCache) {
        this.requestCache = requestCache;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws ServletException, IOException {
		log.debug("UniLogin authentication success - username: {}", authentication.getPrincipal());
    	//清空认证异常
        clearAuthenticationAttributes(request);

        //获取之前保存的请求，即对应OAuth2的认证端点URI
        String redirectUri = Optional.ofNullable(this.requestCache.getRequest(request, response))
                .map(SavedRequest::getRedirectUrl)
                .orElse(null);

        //构建认证成功响应结果
        String respJson = JsonUtils.toJson(UniLoginRespJsonDto.builder()
                .code(AuthenticaionResultCodeEnum.SUCCESS.getCode())
                .redirectUri(redirectUri)
                .build());
		log.debug("UniLogin authentication success resp: {}", respJson);
        HttpContextUtils.responseJson(respJson, response);
    }

    /**
     * Removes temporary authentication-related data which may have been stored in the
     * session during the authentication process.
     */
    protected final void clearAuthenticationAttributes(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
        }
    }

}